package com.duckduckgo.mobile.android.util;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.webkit.WebView;
import com.duckduckgo.mobile.android.network.DDGNetworkConstants;
import info.guardianproject.onionkit.ui.OrbotHelper;
import info.guardianproject.onionkit.web.WebkitProxy;

/**
 * This class implements methods for Tor integration, such as setting and resetting proxy.
 */
public class TorIntegration {

    public static final int JELLY_BEAN_MR2 = 18;
    private final Activity context;
    private final OrbotHelper orbotHelper;
    private Dialog dialogOrbotInstall = null;
    private Dialog dialogOrbotStart = null;


    public TorIntegration(Activity context){
        this.context = context;
        orbotHelper = new OrbotHelper(this.context);
    }

    public boolean prepareTorSettings(){
        return prepareTorSettings(isTorSettingEnabled());
    }

    public boolean prepareTorSettings(boolean enableTor){
        if(!isTorSupported()){
            return false;
        }
        //DDGNetworkConstants.initializeMainClient(context.getApplication(), enableTor);
        if(enableTor){
            DDGNetworkConstants.initializeMainClient(context.getApplication(), enableTor);
            enableOrbotProxy();
            requestOrbotInstallAndStart();
        }
        else{
            resetProxy();
        }
        return true;
    }

    private void resetProxy() {
        try {
            WebkitProxy.resetProxy("com.duckduckgo.mobile.android.DDGApplication", DDGNetworkConstants.getWebView().getContext().getApplicationContext());
        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    public void resetProxy(WebView webView) {
        try {
            WebkitProxy.resetProxy("com.duckduckgo.mobile.android.DDGApplication", webView.getContext().getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void enableOrbotProxy() {
        try {
            WebkitProxy.setProxy("com.duckduckgo.mobile.android.DDGApplication", DDGNetworkConstants.getWebView().getContext().getApplicationContext(), DDGNetworkConstants.getWebView(), DDGNetworkConstants.PROXY_HOST, DDGNetworkConstants.PROXY_HTTP_PORT);
        } catch (Exception e) {
            // what should we do here? Discuss!
            e.printStackTrace();
        }
    }

    public void enableOrbotProxy(WebView webView) {
        try {
            WebkitProxy.setProxy("com.duckduckgo.mobile.android.DDGApplication", webView.getContext().getApplicationContext(), webView, DDGNetworkConstants.PROXY_HOST, DDGNetworkConstants.PROXY_HTTP_PORT);
        } catch (Exception e) {
            // what should we do here? Discuss!
            e.printStackTrace();
        }
    }

    private void requestOrbotInstallAndStart() {
        if (!orbotHelper.isOrbotInstalled()){
            promptToInstall();
        }
        else if (!orbotHelper.isOrbotRunning()){
            requestOrbotStart();
        }
    }

    /**
     * if showing this will dismiss and release all the dialogs generated by TorIntegration
     */
    public void dismissDialogs(){
        dismissOrbotStartDialog();
        dismissOrbotPromptDialog();
    }
    /**
     * This method will dismiss prompt dialog if visible.
     */
    public void dismissOrbotPromptDialog(){
        if(dialogOrbotInstall != null && dialogOrbotInstall.isShowing()){
            dialogOrbotInstall.dismiss();
            dialogOrbotInstall = null;
        }
    }

    /**
     * This method is same as OrbotHelper.promptToInstall except dismisses the previous dialogs and stores the reference of new one.
     */
    public void promptToInstall()
    {
        String uriMarket = context.getString(info.guardianproject.onionkit.R.string.market_orbot);
        // show dialog - install from market, f-droid or direct APK
        dialogOrbotInstall = showDownloadDialog(context.getString(info.guardianproject.onionkit.R.string.install_orbot_),
                context.getString(info.guardianproject.onionkit.R.string.you_must_have_orbot),
                context.getString(info.guardianproject.onionkit.R.string.yes), context.getString(info.guardianproject.onionkit.R.string.no), uriMarket);
    }

    /**
     * This method is taken from OrbotHelper it uses same resource strings but returns the dialog instead.
     * @return AlertDialog instance which can be used later to dismiss when activity is destroying
     */
    private AlertDialog showDownloadDialog(CharSequence stringTitle, CharSequence stringMessage, CharSequence stringButtonYes,
                                           CharSequence stringButtonNo, final String uriString) {
        AlertDialog.Builder downloadDialog = new AlertDialog.Builder(context);
        downloadDialog.setTitle(stringTitle);
        downloadDialog.setMessage(stringMessage);
        downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Uri uri = Uri.parse(uriString);
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                context.startActivity(intent);
            }
        });
        downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
            }
        });
        return downloadDialog.show();
    }
    /**
     * This method will dismiss prompt dialog if visible.
     */
    public void dismissOrbotStartDialog(){
        if(dialogOrbotStart != null && dialogOrbotStart.isShowing()){
            dialogOrbotStart.dismiss();
            dialogOrbotStart = null;
        }
    }
    public void requestOrbotStart()
    {
        dismissOrbotStartDialog();
        AlertDialog.Builder downloadDialog = new AlertDialog.Builder(context);
        downloadDialog.setTitle(info.guardianproject.onionkit.R.string.start_orbot_);
        downloadDialog
                .setMessage(info.guardianproject.onionkit.R.string.orbot_doesn_t_appear_to_be_running_would_you_like_to_start_it_up_and_connect_to_tor_);
        downloadDialog.setPositiveButton(info.guardianproject.onionkit.R.string.yes, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                context.startActivityForResult(orbotHelper.getOrbotStartIntent(), 1);
            }
        });
        downloadDialog.setNegativeButton(info.guardianproject.onionkit.R.string.no, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
            }
        });
        dialogOrbotStart = downloadDialog.show();
    }
    public boolean isTorSettingEnabled() {
        return PreferencesManager.getEnableTor();
    }

    public boolean isOrbotRunningAccordingToSettings() {
        return !isTorSettingEnabled() || isTorEnabledAndOrbotRunning();
    }

    private boolean isTorEnabledAndOrbotRunning(){
        return isTorSettingEnabled() &&
                orbotHelper.isOrbotInstalled() &&
                orbotHelper.isOrbotRunning();
    }

    public boolean isTorSupported() {
        return true; //Build.VERSION.SDK_INT <= JELLY_BEAN_MR2;
    }
}
